import threading

class Statistics:
    def __init__(self, name='', percentage=0.0, step=0):
        self.name_ = name
        self.percentage_ = percentage 
        self.normal_distribution_ = [0] * (2 * step + 1)
        self.min_ = None
        self.max_ = None
        self.sum_ = 0.0
        self.counter_ = 0
        self.mutex_ = threading.Lock()

    def set_name(self, name):
        with self.mutex_:
            self.name_ = name

    def set_percentage_and_step(self, percentage=0.0, step=0):
        with self.mutex_:
            self.min_valid_ = False
            self.max_valid_ = False
            self.sum_ = 0.0
            self.counter_ = 0
            self.percentage_ = percentage
            self.normal_distribution_ = [0] * (2 * step + 1)

    def feed(self, value):
        with self.mutex_:
            self.counter_ += 1
            self.sum_ += value
            if not self.min_valid_:
                self.min_valid_ = True
                self.min_ = value
            elif self.min_ > value:
                self.min_ = value
                
            if not self.max_valid_:
                self.max_valid_ = True
                self.max_ = value
            elif self.max_ < value:
                self.max_ = value

            # ... rest of the function

    def print(self):
        with self.mutex_:
            output = ", ".join(map(str, self.normal_distribution_))
            print(f"print Statistics name_[{self.name_}], percentage_[{self.percentage_}], step[{self.get_step()}], statistics[min:{self.min_}, max:{self.max_}, avg:{self.get_avg()}, sum:{self.sum_}, counter:{self.counter_}], normal_distribution_[{output}]\r\n")

    def get_min(self):
        return self.min_

    def get_max(self):
        return self.max_

    def get_sum(self):
        return self.sum_

    def get_counter(self):
        return self.counter_

    def get_avg(self):
        with self.mutex_:
            return self.sum_ / self.counter_ if self.counter_ != 0 else self.sum_

    def get_percentage(self):
        return self.percentage_

    def get_step(self):
        with self.mutex_:
            return len(self.normal_distribution_) / 2

    def get_normal_distribution(self):
        with self.mutex_:
            return self.normal_distribution_
